Skip to content

fix(linker): correct several cross-toolchain memory map inconsistencies - #126

Open
94xhn wants to merge 1 commit into
STMicroelectronics:masterfrom
94xhn:fix/linker-cross-toolchain-audit
Open

fix(linker): correct several cross-toolchain memory map inconsistencies#126
94xhn wants to merge 1 commit into
STMicroelectronics:masterfrom
94xhn:fix/linker-cross-toolchain-audit

Conversation

@94xhn

@94xhn 94xhn commented Jul 11, 2026

Copy link
Copy Markdown

Not tied to a specific existing issue - found by systematically cross-checking each example's GCC (SW4STM32)/IAR (EWARM)/Keil (MDK-ARM) linker scripts against each other and against known-good Templates/Templates_LL sibling projects for the same chip, following the same methodology already used for STM32CubeG4, STM32CubeWB, and STM32CubeU5 in this repo family.

1. STM32F769I-Discovery and STM32F769I_EVAL (STM32F769NIH6, 2MB flash / 512KB RAM) - 18 examples, EWARM alone wrong

EWARM's .icf declared only 1MB flash (ROM_end=0x080FFFFF) and either 320K or 64K RAM instead of the chip's real 2MB / 512K, across 18 ordinary HAL peripheral examples on both boards. GCC and Keil both already correctly use the full 2MB/512K for the same projects - confirmed via _estack (computed as 0x20080000 = 0x20000000 + 512K) and each project's own GCC MEMORY block. Fixed all 18 EWARM files to ROM_end=0x081FFFFF, RAM_end=0x2007FFFF.

2. STM32F769I_EVAL FatFs example family (6 project identities, 18 files) - EWARM and GCC both wrong

Both EWARM (.icf) and GCC (.ld, across the USB-host-mode SW4STM32 variants) declared only 1MB flash / 320K RAM - only Keil (via its .uvprojx <Cpu> line, IRAM(0x20000000-0x2007FFFF) IROM(0x8000000-0x81FFFFF)) correctly used the full 2MB flash / 512K RAM. This is a "2-of-3-toolchains-wrong" pattern - a naive majority vote across toolchains would have picked the wrong answer here, similar to what was already found once in STM32CubeWB. Fixed EWARM's ROM/RAM end symbols and GCC's FLASH/RAM LENGTH to 2048K/512K in all 6 EWARM .icf + 12 GCC .ld files.

3. NUCLEO-F767ZI (STM32F767ZIT6, 2MB flash / 512KB RAM) - 25 examples, Keil alone wrong

Keil ships no explicit .sct scatter file for these projects - the project's own <Cpu> device-descriptor line in Project.uvprojx is what it actually links against - and that line declared only 320K RAM (IRAM(0x20000000-0x2004FFFF)) instead of the chip's real 512K. Confirmed against GCC/IAR agreement on 512K for the same projects, and cross-checked across two different Keil device-pack versions used by different examples on this board (2.3.3 and 2.7.5), ruling out a pack-specific fluke rather than a real content bug. Fixed the IRAM range to 0x20000000-0x2007FFFF in all 25 files.

The same board's plain Templates project (as opposed to Templates_LL, which already agrees on 512K across all 3 toolchains and served as the gold standard for this finding) had this exact same bug in both its GCC .ld and Keil .uvprojx, with only its own IAR .icf correct - fixed those 2 files too.

Test plan

No local ARM toolchain (arm-none-eabi-gcc/IAR/Keil) available to compile/link-test these, so verification relied on address-arithmetic cross-referencing for each finding against multiple independent references: Templates/Templates_LL gold standards, sibling toolchain files of the same project, and checking _estack/actual linker symbol usage rather than trusting MEMORY{}/Cpu-line declarations alone.

Note on scope

A 4th candidate was found (STM32F7308-DISCO / STM32F7508-DISCO, flash-less QSPI-execute-in-place parts where Keil ships with no scatter file at all and falls back to a non-functional 64KB internal-flash default) but is not included in this PR - fixing it would require authoring a new Keil scatter file for QSPI XIP from scratch rather than correcting an existing value, which is a larger, more design-heavy change that deserves its own separate scrutiny/PR rather than being bundled here.

Disclosure

Generative AI (Claude) was used to help investigate this (systematic cross-toolchain linker script comparison) and implement/verify the fixes. All changes were reviewed by me before submission.

Found by cross-checking each example's GCC (SW4STM32)/IAR (EWARM)/Keil
(MDK-ARM) linker scripts against each other and against known-good
Templates/Templates_LL sibling projects, following the same audit
already done for STM32CubeG4/STM32CubeWB/STM32CubeU5 in this repo
family.

1. STM32F769I-Discovery and STM32F769I_EVAL (STM32F769NIH6, 2MB
   flash/512KB RAM), 18 ordinary HAL peripheral examples: EWARM's .icf
   declared only 1MB flash (ROM_end=0x080FFFFF) and 320K or 64K RAM
   instead of the chip's real 2MB/512K. GCC and Keil both already
   correctly use the full 2MB/512K for the same projects (confirmed via
   `_estack` and the GCC MEMORY block in each project). Fixed all 18
   EWARM files to ROM_end=0x081FFFFF, RAM_end=0x2007FFFF.

2. STM32F769I_EVAL FatFs example family (6 project identities, 18
   files: 6 EWARM .icf + 12 SW4STM32 .ld across USB host mode
   variants): both EWARM AND GCC declared only 1MB flash / 320K RAM -
   only Keil (via its .uvprojx Cpu line) correctly used the full 2MB
   flash / 512K RAM. This is the "2-of-3-toolchains-wrong" pattern
   already seen once in STM32CubeWB - majority vote across toolchains
   would have picked the wrong answer here. Fixed EWARM ROM/RAM ends
   and GCC FLASH/RAM LENGTH to 2048K/512K.

3. NUCLEO-F767ZI (STM32F767ZIT6, 2MB flash/512KB RAM), 25 example/
   application projects: Keil (no explicit .sct shipped; the project's
   own <Cpu> device-descriptor line in Project.uvprojx is what it
   actually links against) declared only 320K RAM
   (IRAM(0x20000000-0x2004FFFF)) instead of the chip's real 512K.
   Confirmed against GCC/IAR agreement on 512K for the same projects,
   and cross-checked across two different Keil device-pack versions
   used by different examples on this board (2.3.3 and 2.7.5), ruling
   out a pack-specific fluke. Fixed the IRAM range to
   0x20000000-0x2007FFFF in all 25 files.

   Same board's plain Templates project (as opposed to Templates_LL,
   which already agrees on 512K across all 3 toolchains and served as
   the gold standard here) had this exact same bug in both its GCC .ld
   and Keil .uvprojx, with only its own IAR .icf correct - fixed those
   2 files too.

No local ARM toolchain (arm-none-eabi-gcc/IAR/Keil) available to
compile/link-test these changes; verification relied on
address-arithmetic cross-referencing against multiple independent
references per finding (Templates/Templates_LL gold standards, sibling
toolchain files of the same project, and `_estack`/actual linker
symbol usage, not just MEMORY{}/Cpu-line declarations).

A 4th candidate (STM32F7308-DISCO/STM32F7508-DISCO, flash-less
QSPI-execute-in-place parts where Keil ships with no scatter file at
all and falls back to a non-functional 64KB internal-flash default) is
not included here - fixing it would require authoring a new Keil
scatter file for QSPI XIP rather than correcting an existing value, a
larger and more design-heavy change that needs more scrutiny before a
PR.

Signed-off-by: 94xhn <87560781+94xhn@users.noreply.github.com>
@ALABSTM ALABSTM added bug Something isn't working projects Projects-related (demos, applications, examples) issue or pull-request. labels Jul 13, 2026
@ASAHSTM ASAHSTM moved this from To do to Analyzed in stm32cube-mcu-fw-dashboard Jul 17, 2026
@ASAHSTM

ASAHSTM commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Hello @94xhn,

Thank you for these fixes. This has been tracked internally.

With Regards,

@ASAHSTM

ASAHSTM commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

ST Internal Reference: 1ba5b4e783928b50e4a3dd112fda1e24

@ASAHSTM ASAHSTM added the internal bug tracker Issue confirmed and logged into the internal bug tracking system label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working internal bug tracker Issue confirmed and logged into the internal bug tracking system projects Projects-related (demos, applications, examples) issue or pull-request.

Projects

Development

Successfully merging this pull request may close these issues.

3 participants